package com.tianheng.wanzhou.datacollecting.netty.kongyajiR150.client;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tianheng.wanzhou.datacollecting.db.entity.MachineList;
import com.tianheng.wanzhou.datacollecting.db.service.IMachineListService;
import com.tianheng.wanzhou.datacollecting.util.StrUtil;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.util.ReferenceCountUtil;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;


/**
 * @Author: yujw
 * @Date: 2020/5/12 14:13
 * @Version 1.0
 */
@Component(value = "kongyajiR150Client")
public class MyClient {

    @Autowired
    private ObjectFactory<ClientHandler> factory;
    @Autowired
    IMachineListService machineListService;

    private List<MachineList> machineList = new ArrayList<>();

    private BlockingQueue<String> queue = new LinkedBlockingQueue<>(100);

    //netty组件
    EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
    Bootstrap bs = new Bootstrap();


    MyClient() {
        bs.group(eventLoopGroup)
                .channel(NioSocketChannel.class)
                .option(ChannelOption.SO_KEEPALIVE, true)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        ch.pipeline().addLast(factory.getObject())
                                .addLast("GatherDecoder", new GatherDecoder());
                    }
                });
    }

    @PostConstruct
    private void postConstruct() {
        QueryWrapper<MachineList> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("mac_type", 2).eq("status", 1).eq("son_type", "02");
        machineList = machineListService.list(queryWrapper);
//        queue.offer("01010000007DFC2B");
//        queue.offer("01020000007DB82B");
        //plc数据
//        queue.offer("01030032004925F3");
//        queue.offer("0103000F0011B5C5");
//        queue.offer("01030514002B451D");
//        queue.offer("01030190001AC5D0");
//        queue.offer("01030733001BF4BA");
//        queue.offer("0103074E002764B3");
        //屏幕数据
        queue.offer("01030212000265B6");
        queue.offer("0103024400034466");
        queue.offer("010302760004A46B");
        queue.offer("010302A800050591");
        queue.offer("010302DA0006E58B");
        queue.offer("0103030C0007C44F");
        queue.offer("0103033E00082584");
        queue.offer("0103037000098453");
        queue.offer("010303D4000E8472");
        queue.offer("0103046A000AE4E1");
        queue.offer("0103049C000BC513");
        queue.offer("010304CE000C2500");
        queue.offer("01030052000D25DE");

    }

    @Scheduled(cron = "0/10 * * * * ? ")
    public void sendMsg() {
        for (MachineList machine : this.machineList) {
//            ChannelFuture cf = bs.connect(machine.getMacIp(), machine.getPort()).sync();
            try{
                int queueLength = queue.size();
                for (int i = 0; i < queueLength; i++) {
                    ChannelFuture cf = bs.connect(machine.getMacIp(), machine.getPort()).sync();
                    ByteBuf byteBuf = Unpooled.buffer();
                    byteBuf.retain();
                    String data = queue.poll();
                    queue.offer(data);
                    byte[] bytes = StrUtil.hexStr2Byte(data);
                    byteBuf.writeBytes(bytes);
                    cf.channel().writeAndFlush(byteBuf);
                    ReferenceCountUtil.release(byteBuf);
                    Thread.sleep(1000);
                }
            }catch (Exception e) {
                System.err.println(machine.getMacIp()+"连接失败" + e.getMessage());
            }



//            读01
//            ByteBuf byteBuf = Unpooled.buffer();
//            byteBuf.retain();
//            byte[] bytes0 = StrUtil.hexStr2Byte();
//            byteBuf.writeBytes(bytes0);
//            cf.channel().writeAndFlush(byteBuf);
//            ReferenceCountUtil.release(byteBuf);
//            Thread.sleep(1000);
//            //读02
//            ByteBuf byteBuf1 = Unpooled.buffer();
//            byte[] bytes1 = StrUtil.hexStr2Byte("01020000007DB82B");
//            byteBuf.writeBytes(bytes1);
//            cf.channel().writeAndFlush(byteBuf1);
//            ReferenceCountUtil.release(byteBuf);
//            Thread.sleep(1000);
//
//            //读03
//            //读单寄存器
//            //屏幕数据
//            //01
//            ByteBuf byteBuf2 = Unpooled.buffer();
//            byte[] bytes2 = StrUtil.hexStr2Byte("01030212000125B7");
//            byteBuf2.writeBytes(bytes2);
//            cf.channel().writeAndFlush(byteBuf2);
//            ReferenceCountUtil.release(byteBuf);
//            Thread.sleep(1000);
//
//            //02
//            ByteBuf byteBuf3 = Unpooled.buffer();
//            bytes2 = StrUtil.hexStr2Byte("01030244000285A6");
//            byteBuf3.writeBytes(bytes2);
//            cf.channel().writeAndFlush(byteBuf3);
//            ReferenceCountUtil.release(byteBuf);
//            Thread.sleep(1000);
//
//            //03
//            ByteBuf byteBuf4 = Unpooled.buffer();
//            bytes2 = StrUtil.hexStr2Byte("010302760003E5A9");
//            byteBuf4.writeBytes(bytes2);
//            cf.channel().writeAndFlush(byteBuf4);
//            ReferenceCountUtil.release(byteBuf);
//            Thread.sleep(1000);
//
//            //04
//            ByteBuf byteBuf5 = Unpooled.buffer();
//            bytes2 = StrUtil.hexStr2Byte("010302A80004C451");
//            byteBuf5.writeBytes(bytes2);
//            cf.channel().writeAndFlush(byteBuf5);
//            ReferenceCountUtil.release(byteBuf);
//            Thread.sleep(1000);
//
//            //05
//            ByteBuf byteBuf6 = Unpooled.buffer();
//            bytes2 = StrUtil.hexStr2Byte("010302DA0005A58A");
//            byteBuf6.writeBytes(bytes2);
//            cf.channel().writeAndFlush(byteBuf6);
//            ReferenceCountUtil.release(byteBuf);
//            Thread.sleep(1000);
//
//            //06
//            ByteBuf byteBuf7 = Unpooled.buffer();
//            bytes2 = StrUtil.hexStr2Byte("0103030C0006058F");
//            byteBuf7.writeBytes(bytes2);
//            cf.channel().writeAndFlush(byteBuf7);
//            ReferenceCountUtil.release(byteBuf);
//            Thread.sleep(1000);
//
//            //07
//            ByteBuf byteBuf8 = Unpooled.buffer();
//            bytes2 = StrUtil.hexStr2Byte("0103033E00076580");
//            byteBuf8.writeBytes(bytes2);
//            cf.channel().writeAndFlush(byteBuf8);
//            ReferenceCountUtil.release(byteBuf);
//            Thread.sleep(1000);
//
//            //08
//            ByteBuf byteBuf9 = Unpooled.buffer();
//            bytes2 = StrUtil.hexStr2Byte("0103037000084593");
//            byteBuf9.writeBytes(bytes2);
//            cf.channel().writeAndFlush(byteBuf9);
//            ReferenceCountUtil.release(byteBuf);
//            Thread.sleep(1000);
//
//            //09
//            ByteBuf byteBuf10 = Unpooled.buffer();
//            bytes2 = StrUtil.hexStr2Byte("010303A20009246A");
//            byteBuf10.writeBytes(bytes2);
//            cf.channel().writeAndFlush(byteBuf10);
//            ReferenceCountUtil.release(byteBuf);
//            Thread.sleep(1000);
//
//            //0A
//            ByteBuf byteBuf11 = Unpooled.buffer();
//            bytes2 = StrUtil.hexStr2Byte("010303D4000A85B1");
//            byteBuf11.writeBytes(bytes2);
//            cf.channel().writeAndFlush(byteBuf11);
//            ReferenceCountUtil.release(byteBuf);
//            Thread.sleep(1000);
//
//            //0B
//            ByteBuf byteBuf12 = Unpooled.buffer();
//            bytes2 = StrUtil.hexStr2Byte("01030406000BE53C");
//            byteBuf12.writeBytes(bytes2);
//            cf.channel().writeAndFlush(byteBuf12);
//            ReferenceCountUtil.release(byteBuf);
//            Thread.sleep(1000);
//
//            //0C
//            ByteBuf byteBuf13 = Unpooled.buffer();
//            bytes2 = StrUtil.hexStr2Byte("01030438000CC532");
//            byteBuf13.writeBytes(bytes2);
//            cf.channel().writeAndFlush(byteBuf13);
//            Thread.sleep(1000);
//
//            //0D
//            ByteBuf byteBuf14 = Unpooled.buffer();
//            bytes2 = StrUtil.hexStr2Byte("0103046A000DA523");
//            byteBuf14.writeBytes(bytes2);
//            cf.channel().writeAndFlush(byteBuf14);
//            ReferenceCountUtil.release(byteBuf);
//            Thread.sleep(1000);
//
//            //0E
//            ByteBuf byteBuf15 = Unpooled.buffer();
//            bytes2 = StrUtil.hexStr2Byte("0103049C000E0510");
//            byteBuf15.writeBytes(bytes2);
//            cf.channel().writeAndFlush(byteBuf15);
//            ReferenceCountUtil.release(byteBuf);
//            Thread.sleep(1000);
//
//            //0F
//            ByteBuf byteBuf16 = Unpooled.buffer();
//            bytes2 = StrUtil.hexStr2Byte("010304CE000F6501");
//            byteBuf16.writeBytes(bytes2);
//            cf.channel().writeAndFlush(byteBuf16);
//            ReferenceCountUtil.release(byteBuf);
//            Thread.sleep(1000);
//
//            //10
//            ByteBuf byteBuf17 = Unpooled.buffer();
//            bytes2 = StrUtil.hexStr2Byte("01030500001044CA");
//            byteBuf17.writeBytes(bytes2);
//            cf.channel().writeAndFlush(byteBuf17);
//            ReferenceCountUtil.release(byteBuf);
//            Thread.sleep(1000);
//            //----
//
//
//            //40016
//            //11
//            ByteBuf byteBuf18 = Unpooled.buffer();
//            bytes2 = StrUtil.hexStr2Byte("0103000F0011B5C5");
//            byteBuf18.writeBytes(bytes2);
//            cf.channel().writeAndFlush(byteBuf18);
//            ReferenceCountUtil.release(byteBuf);
//            Thread.sleep(1000);
//
//            //40123
//            //12
//            ByteBuf byteBuf19 = Unpooled.buffer();
//            bytes2 = StrUtil.hexStr2Byte("0103007A0012E41E");
//            byteBuf19.writeBytes(bytes2);
//            cf.channel().writeAndFlush(byteBuf19);
//            ReferenceCountUtil.release(byteBuf);
//            Thread.sleep(1000);
//
//            //41301
//            //13
//            ByteBuf byteBuf20 = Unpooled.buffer();
//            bytes2 = StrUtil.hexStr2Byte("01030514001344CF");
//            byteBuf20.writeBytes(bytes2);
//            cf.channel().writeAndFlush(byteBuf20);
//            ReferenceCountUtil.release(byteBuf);
//            Thread.sleep(1000);
//
//            //41322
//            //14
//            ByteBuf byteBuf21 = Unpooled.buffer();
//            bytes2 = StrUtil.hexStr2Byte("01030529001494C1");
//            byteBuf21.writeBytes(bytes2);
//            cf.channel().writeAndFlush(byteBuf21);
//            ReferenceCountUtil.release(byteBuf);
//            Thread.sleep(1000);
//
//            //41343
//            //15
//            ByteBuf byteBuf22 = Unpooled.buffer();
//            bytes2 = StrUtil.hexStr2Byte("0103053E0015E505");
//            byteBuf22.writeBytes(bytes2);
//            cf.channel().writeAndFlush(byteBuf22);
//            ReferenceCountUtil.release(byteBuf);
//            Thread.sleep(1000);
//
//            //多个寄存器
//            //40083-40089 8
//            //16
//            ByteBuf byteBuf23 = Unpooled.buffer();
//            bytes2 = StrUtil.hexStr2Byte("010300520016E5DD");
//            byteBuf23.writeBytes(bytes2);
//            cf.channel().writeAndFlush(byteBuf23);
//            ReferenceCountUtil.release(byteBuf);
//            Thread.sleep(1000);
//
//
//            //40401-40410 20
//            //1A
//            ByteBuf byteBuf24 = Unpooled.buffer();
//            bytes2 = StrUtil.hexStr2Byte("01030190001AC5D0");
//            byteBuf24.writeBytes(bytes2);
//            cf.channel().writeAndFlush(byteBuf24);
//            ReferenceCountUtil.release(byteBuf);
//            Thread.sleep(1000);
//
//            //41844-41850 8
//            //1B
//            ByteBuf byteBuf25 = Unpooled.buffer();
//            bytes2 = StrUtil.hexStr2Byte("01030733001BB577");
//            byteBuf25.writeBytes(bytes2);
//            cf.channel().writeAndFlush(byteBuf25);
//            ReferenceCountUtil.release(byteBuf25);
//            Thread.sleep(1000);
//
//            //41871-41889 20
//            //20
//            ByteBuf byteBuf26 = Unpooled.buffer();
//            bytes2 = StrUtil.hexStr2Byte("0103074E00202571");
//            byteBuf26.writeBytes(bytes2);
//            cf.channel().writeAndFlush(byteBuf26);
//            ReferenceCountUtil.release(byteBuf26);
//            Thread.sleep(1000);

        }
    }

    //隔一小时更新一次设备列表
    @Scheduled(cron = "0 0 0/1 * * ?")
    public void updateMacList() {
        QueryWrapper<MachineList> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("mac_type", 2).eq("status", 1).eq("son_type", "02");
        machineList = machineListService.list(queryWrapper);
    }
}
